<html>
<head><meta charset="utf-8"><title>symbol mangling v0 ✕ polymorphisation · t-compiler/wg-polymorphization · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/index.html">t-compiler/wg-polymorphization</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html">symbol mangling v0 ✕ polymorphisation</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="206152008"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206152008" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206152008">(Aug 06 2020 at 14:55)</a>:</h4>
<p><span class="user-mention" data-user-id="119009">@eddyb</span> I've been looking into the failure that happens when polymorphisation and new symbol mangling are enabled. I don't have a small reproduction yet, but I've got a sense of what the issue is.</p>
<p>So, the compiler fails when compiling <code>term</code> in stage1-std with the following:</p>
<div class="codehilite"><pre><span></span><code>error: symbol `_RNCINvMs3_NtCskT7Ax6nvWhX_9hashbrown3rawINtB8_8RawTableTNtNtCsdLyrxDMQERL_5alloc6string6StringINtNtBW_3vec3VechEEE15rehash_in_placepEs_0CsfCyaVWJOVxl_4term` is already defined
</code></pre></div>


<p>When demangled, we get: </p>
<div class="codehilite"><pre><span></span><code>&lt;hashbrown::raw::RawTable&lt;(alloc::string::String, alloc::vec::Vec&lt;u8&gt;)&gt;&gt;::rehash_in_place::&lt;_&gt;::{closure#1}
</code></pre></div>


<p>This error is thrown from the partitioner:</p>
<p><a href="https://github.com/rust-lang/rust/blob/3cfc7fe78eccc754b16981704a098d7bd520e2fd/src/librustc_mir/monomorphize/partitioning.rs#L872-L878">https://github.com/rust-lang/rust/blob/3cfc7fe78eccc754b16981704a098d7bd520e2fd/src/librustc_mir/monomorphize/partitioning.rs#L872-L878</a></p>
<p>It happens because there are two mono items which end up having the same mangling. In particular, it is the mono item for this closure in hashbrown:</p>
<p><a href="https://github.com/rust-lang/hashbrown/blob/7593ec95d097ace1e111b9a862f72a8db7eeddf2/src/raw/mod.rs#L798-L801">https://github.com/rust-lang/hashbrown/blob/7593ec95d097ace1e111b9a862f72a8db7eeddf2/src/raw/mod.rs#L798-L801</a></p>
<p>There are two generic parameters in scope: <code>T</code> from the impl and <code>impl Fn(&amp;T) -&gt; u64</code> from the arguments; Polymorphisation correctly determines that the <code>impl Fn(&amp;T) -&gt; u64</code> parameter is not used by the closure and polymorphises.</p>
<p><code>T</code> varies a handful of times with <code>rehash_in_place</code>, and what I'm about to describe is true regardless, but I'll stick with <code>T</code> being <code>(std::string::String, std::vec::Vec&lt;u8&gt;)</code> for this explanation:</p>
<p>At the point where the mono item is added to the mono item set in collection, the mono item looks like this:</p>
<div class="codehilite"><pre><span></span><code>Fn(
    Instance {
        def: Item(
            WithOptConstParam {
                did: DefId(9:140 ~ hashbrown[f34e]::raw[0]::{{impl}}[5]::rehash_in_place[0]::{{closure}}[1]),
                const_param_did: None,
            },
        ),
        substs: [
            (std::string::String, std::vec::Vec&lt;u8&gt;),
            impl Fn(&amp;T) -&gt; u64,
            i8,
            extern &quot;rust-call&quot; fn((usize,)) -&gt; usize,
            (&amp;hashbrown::scopeguard::ScopeGuard&lt;&amp;mut hashbrown::raw::RawTable&lt;(std::string::String, std::vec::Vec&lt;u8&gt;)&gt;, [closure@hashbrown::raw::RawTable::&lt;T&gt;::rehash_in_place::{{closure}}#0]&gt;, &amp;u64),
        ],
    },
)
</code></pre></div>


<div class="spoiler-block"><div class="spoiler-header">

<p>with -Zverbose</p>
</div><div class="spoiler-content" aria-hidden="true">

<div class="codehilite"><pre><span></span><code>Fn(
    Instance {
        def: Item(
            WithOptConstParam {
                did: DefId(9:140 ~ hashbrown[f34e]::raw[0]::{{impl}}[5]::rehash_in_place[0]::{{closure}}[1]),
                const_param_did: None,
            },
        ),
        substs: [
            (std::string::String, std::vec::Vec&lt;u8&gt;),
            impl Fn(&amp;T) -&gt; u64,
            i8,
            extern &quot;rust-call&quot; fn((usize,)) -&gt; usize,
            (&amp;ReErased hashbrown::scopeguard::ScopeGuard&lt;&amp;ReErased mut hashbrown::raw::RawTable&lt;(std::string::String, std::vec::Vec&lt;u8&gt;)&gt;, [closure@hashbrown::raw::RawTable::&lt;T&gt;::rehash_in_place::{{closure}}#0 closure_kind_ty=i16 closure_sig_as_fn_ptr_ty=for&lt;&#39;r&gt; extern &quot;rust-call&quot; fn((&amp;ReLateBound(DebruijnIndex(0), BrNamed(&#39;r)) mut &amp;ReErased mut hashbrown::raw::RawTable&lt;(std::string::String, std::vec::Vec&lt;u8&gt;)&gt;,))]&gt;, &amp;ReErased u64),
        ],
    },
)
</code></pre></div>


</div></div>

<p>The mono item is added to the set, and later is visited again (being in the set already, it just continues on). But, slightly later again, the mono item is added for a second time (i.e. it has a different hash - I've verified this)!  Like the first time, this second mono item with the different hash later gets visited again and is already in the set so nothing happens.</p>
<p>After collection, that mono item ends up being in the set twice. In debug output (with or without <code>-Zverbose</code>), there is no difference between the two mono items. The mono item ends up in the set twice regardless of polymorphisation being enabled or mangling scheme.</p>
<p>Without polymorphisation, the mangling (with the new scheme) looks like this:</p>
<div class="codehilite"><pre><span></span><code><span class="gp">$</span> rustfilt _RNCINvMs3_NtCskT7Ax6nvWhX_9hashbrown3rawINtB8_8RawTableTNtNtCsdLyrxDMQERL_5alloc6string6StringINtNtBW_3vec3VechEEE15rehash_in_placeNCNvMs_NtBa_3mapINtB2c_7HashMapBS_B1u_NtNtNtNtCs269B1xf5mBU_3std11collections4hash3map11RandomStateE6inserts_0Es_0CsbDqzXfLQacH_4term
<span class="go">&lt;hashbrown::raw::RawTable&lt;(alloc::string::String, alloc::vec::Vec&lt;u8&gt;)&gt;&gt;::rehash_in_place::&lt;&lt;hashbrown::map::HashMap&lt;alloc::string::String, alloc::vec::Vec&lt;u8&gt;, std::collections::hash::map::RandomState&gt;&gt;::insert::{closure#1}&gt;::{closure#1}</span>

<span class="gp">$</span> rustfilt _RNCINvMs3_NtCskT7Ax6nvWhX_9hashbrown3rawINtB8_8RawTableTNtNtCsdLyrxDMQERL_5alloc6string6StringINtNtBW_3vec3VechEEE15rehash_in_placeNCNvMs_NtBa_3mapINtB2c_7HashMapBS_B1u_NtNtNtNtCs269B1xf5mBU_3std11collections4hash3map11RandomStateE7reserve0Es_0CsbDqzXfLQacH_4term
<span class="go">&lt;hashbrown::raw::RawTable&lt;(alloc::string::String, alloc::vec::Vec&lt;u8&gt;)&gt;&gt;::rehash_in_place::&lt;&lt;hashbrown::map::HashMap&lt;alloc::string::String, alloc::vec::Vec&lt;u8&gt;, std::collections::hash::map::RandomState&gt;&gt;::reserve::{closure#0}&gt;::{closure#1}</span>
</code></pre></div>


<p>With polymorphisation, the mangling (with the old scheme) looks like this:</p>
<div class="codehilite"><pre><span></span><code><span class="gp">$</span> c++filt _ZN9hashbrown3raw17RawTable<span class="nv">$LT$T$GT$15</span>rehash_in_place28_<span class="nv">$u7b$$</span>u7b<span class="nv">$closure$u7d$$</span>u7d<span class="nv">$17</span>hffd29c03a59d2d61E
<span class="go">hashbrown::raw::RawTable&lt;T&gt;::rehash_in_place::{{closure}}</span>
<span class="gp">$</span> c++filt _ZN9hashbrown3raw17RawTable<span class="nv">$LT$T$GT$15</span>rehash_in_place28_<span class="nv">$u7b$$</span>u7b<span class="nv">$closure$u7d$$</span>u7d<span class="nv">$17</span>hb4cefa7da8459e90E
<span class="go">hashbrown::raw::RawTable&lt;T&gt;::rehash_in_place::{{closure}}</span>
</code></pre></div>


<p>As far as I can tell, the only difference is the end (which I believe is the hash we add) - otherwise these are identical.</p>
<p>Therefore, I believe that polymorphisation isn't at fault here, it's polymorphising what I would expect; and that the mangling schemes are both behaving correctly - it's just that the new scheme doesn't add a hash to the end which when combined with polymorphisation exposes this problem.</p>
<p>I've yet to work out exactly how the mono items are different such that they hash differently and aren't equal. When breaking the mono item down into components and checking for equality, I find that it is the final substitution which differs:</p>
<div class="codehilite"><pre><span></span><code>(&amp;hashbrown::scopeguard::ScopeGuard&lt;&amp;mut hashbrown::raw::RawTable&lt;(std::string::String, std::vec::Vec&lt;u8&gt;)&gt;, [closure@hashbrown::raw::RawTable::&lt;T&gt;::rehash_in_place::{{closure}}#0]&gt;, &amp;u64),
</code></pre></div>


<p>Do you have any thoughts as to how I should proceed next?</p>



<a name="206238753"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206238753" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206238753">(Aug 07 2020 at 09:33)</a>:</h4>
<p>I left this yesterday after sending the message but after thinking about it overnight, I've worked out what a repro would look like:</p>
<div class="codehilite"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">f</span>: <span class="nc">impl</span><span class="w"> </span><span class="nb">Fn</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">|</span><span class="n">_</span>: <span class="p">()</span><span class="o">|</span><span class="w"> </span><span class="p">();</span><span class="w"></span>

<span class="w">    </span><span class="c1">// Don&#39;t use `f` in `y`, but refer to `x` so that the closure substs contain a reference to</span>
<span class="w">    </span><span class="c1">// `x` that will differ for each instantiation despite polymorphisation of the varying</span>
<span class="w">    </span><span class="c1">// argument.</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">x</span><span class="p">(());</span><span class="w"></span>

<span class="w">    </span><span class="c1">// Consider `f` used in `foo`.</span>
<span class="w">    </span><span class="n">f</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="c1">// Use `y` so that it is visited in monomorphisation collection.</span>
<span class="w">    </span><span class="n">y</span><span class="p">();</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">entry_a</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">foo</span><span class="p">(</span><span class="o">||</span><span class="w"> </span><span class="p">());</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">entry_b</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">foo</span><span class="p">(</span><span class="o">||</span><span class="w"> </span><span class="p">());</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">entry_a</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="n">entry_b</span><span class="p">();</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>


<p>This will fail with <code>-Zpolymorphize=on -Zsymbol-mangling-version=v0</code> and produce the following error:</p>
<div class="codehilite"><pre><span></span><code>error: symbol `_RNCINvCs4fqI2P2rA04_3foo3foopEs_0B4_` is already defined
 --&gt; ./foo.rs:7:13
  |
7 |     let y = || x(());
  |             ^^^^^^^^

error: aborting due to previous error
</code></pre></div>



<a name="206238970"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206238970" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206238970">(Aug 07 2020 at 09:36)</a>:</h4>
<p>The issue is that polymorphisation doesn't change the closure's substs (normally it only looks at the parent substs):</p>
<p><a href="https://github.com/rust-lang/rust/blob/9dbbc9b7348a0d8385685610ca95a42f96c2cae5/src/librustc_mir/monomorphize/polymorphize.rs#L97-L100">https://github.com/rust-lang/rust/blob/9dbbc9b7348a0d8385685610ca95a42f96c2cae5/src/librustc_mir/monomorphize/polymorphize.rs#L97-L100</a></p>
<p>This means that when the upvars contain another closure from the function then that won't get polymorphised and will have unpolymorphised substs (so this closure will still vary on all parameters, despite polymorphisation).</p>



<a name="206251322"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206251322" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206251322">(Aug 07 2020 at 12:36)</a>:</h4>
<p>Alright, good news and bad news:</p>
<p>Good news is I've fixed the issue described above - the PR is at <a href="https://github.com/rust-lang/rust/issues/75255">#75255</a>.</p>
<p>Bad news is that when polymorphisation and new symbol mangling are enabled, we still fail to bootstrap - and this time, the issue seems more challenging to tackle.</p>



<a name="206251798"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206251798" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206251798">(Aug 07 2020 at 12:42)</a>:</h4>
<p>Consider the closure in this function:</p>
<p><a href="https://github.com/rust-lang/rust/blob/ac48e62db85e6db4bbe026490381ab205f4a614d/library/core/src/iter/adapters/mod.rs#L2611-L2619">https://github.com/rust-lang/rust/blob/ac48e62db85e6db4bbe026490381ab205f4a614d/library/core/src/iter/adapters/mod.rs#L2611-L2619</a></p>
<p>Polymorphisation correctly determines that <code>I</code> and <code>E</code> are unused; but <code>T</code> is used (from the argument to the closure, I believe). The new symbol mangling produces the following symbol:</p>
<div class="codehilite"><pre><span></span><code>_RNCNvXs1s_NtNtCsfnEnqCNU58Z_4core4iter8adaptersINtB8_11ResultShuntppENtNtNtBa_6traits8iterator8Iterator4next0CseuWsz8kRVmn_18tracing_subscriber
</code></pre></div>


<div class="codehilite"><pre><span></span><code>&lt;core::iter::adapters::ResultShunt&lt;_, _&gt; as core::iter::traits::iterator::Iterator&gt;::next::{closure#0}
</code></pre></div>


<p>This is correct but it doesn't encode the variation on <code>T</code> - so two mono items can be distinct (and I believe correctly) in <code>T</code>, but produce the same symbol. This seems like an issue to be fixed in the mangling scheme to me (hoping that I'm wrong), but that only really happens when polymorphisation is enabled.</p>



<a name="206251936"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206251936" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206251936">(Aug 07 2020 at 12:44)</a>:</h4>
<p>Here are the two polymorphised mono items which conflict:</p>
<div class="codehilite"><pre><span></span><code>mono_item1=Fn(
    Instance {
        def: Item(
            WithOptConstParam {
                did: DefId(2:4572 ~ core[b328]::iter[0]::adapters[0]::{{impl}}[92]::next[0]::{{closure}}[0]),
                const_param_did: None,
            },
        ),
        substs: [
            ReErased,
            I,
            filter::env::directive::Directive,
            E,
            i16,
            for&lt;&#39;r&gt; extern &quot;rust-call&quot; fn((&amp;&#39;r filter::env::directive::Directive,)) -&gt; bool,
            (),
        ],
    },
)

mono_item2=Fn(
    Instance {
        def: Item(
            WithOptConstParam {
                did: DefId(2:4572 ~ core[b328]::iter[0]::adapters[0]::{{impl}}[92]::next[0]::{{closure}}[0]),
                const_param_did: None,
            },
        ),
        substs: [
            ReErased,
            I,
            filter::env::field::Match,
            E,
            i16,
            for&lt;&#39;r&gt; extern &quot;rust-call&quot; fn((&amp;&#39;r filter::env::field::Match,)) -&gt; bool,
            (),
        ],
    },
)
</code></pre></div>



<a name="206252012"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206252012" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206252012">(Aug 07 2020 at 12:44)</a>:</h4>
<p>I've not dug any further to work out which code instantiates both of these, just that the failure is in compiling <code>tracing-subscriber</code> in stage2-rustc.</p>



<a name="206252053"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206252053" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206252053">(Aug 07 2020 at 12:45)</a>:</h4>
<p>cc <span class="user-mention" data-user-id="119009">@eddyb</span> again, just in case you missed the last ping</p>



<a name="206252463"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206252463" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206252463">(Aug 07 2020 at 12:49)</a>:</h4>
<p>I intend to create an repro of that shortly (going to get lunch which I've kept putting off to look into this).</p>



<a name="206256666"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206256666" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206256666">(Aug 07 2020 at 13:30)</a>:</h4>
<div class="codehilite"><pre><span></span><code><span class="c1">// build-pass</span>
<span class="c1">// compile-flags: -Zpolymorphize=on -Zsymbol-mangling-version=v0</span>

<span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Foo</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="p">,</span><span class="w"> </span><span class="n">I</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span><span class="n">I</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="n">E</span><span class="p">);</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="p">,</span><span class="w"> </span><span class="n">I</span><span class="p">,</span><span class="w"> </span><span class="n">T</span>: <span class="na">&#39;a</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">Iterator</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Foo</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="p">,</span><span class="w"> </span><span class="n">I</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">&gt;</span><span class="w"></span>
<span class="k">where</span><span class="w"></span>
<span class="w">    </span><span class="n">I</span>: <span class="nb">Iterator</span><span class="o">&lt;</span><span class="n">Item</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="p">(</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="p">)</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">Item</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">T</span><span class="p">;</span><span class="w"></span>

<span class="w">    </span><span class="k">fn</span> <span class="nf">next</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;</span><span class="bp">Self</span>::<span class="n">Item</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="w"> </span><span class="kc">true</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Foo</span><span class="p">([(</span><span class="mi">1</span><span class="k">u32</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="k">u16</span><span class="p">)].</span><span class="n">iter</span><span class="p">(),</span><span class="w"> </span><span class="o">&amp;</span><span class="mi">1</span><span class="k">u16</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Foo</span><span class="p">([(</span><span class="mi">1</span><span class="k">u16</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="k">u32</span><span class="p">)].</span><span class="n">iter</span><span class="p">(),</span><span class="w"> </span><span class="o">&amp;</span><span class="mi">1</span><span class="k">u32</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="n">next</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">b</span><span class="p">.</span><span class="n">next</span><span class="p">();</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="206256678"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206256678" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206256678">(Aug 07 2020 at 13:30)</a>:</h4>
<div class="codehilite"><pre><span></span><code>error: symbol `_RNCNvXCs4fqI2P2rA04_19impl_param_manglingINtB4_3FooppENtNtNtNtCsfnEnqCNU58Z_4core4iter6traits8iterator8Iterator4next0B4_` is already defined
  --&gt; src/test/ui/polymorphization/impl-param-mangling.rs:13:19
   |
13 |         self.find(|_| true)
   |                   ^^^^^^^^

error: aborting due to previous error
</code></pre></div>



<a name="206365189"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206365189" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206365189">(Aug 08 2020 at 21:40)</a>:</h4>
<p>I think the proper, but probably hard, solution would be to look at dependencies in generics and then encode those.</p>



<a name="206365206"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206365206" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206365206">(Aug 08 2020 at 21:41)</a>:</h4>
<p>So for instance in the linked code the associated <code>type Item = T</code> depends on generic <code>I</code>, so if the closure depends on <code>T</code>, we probably want to also encode (into the symbol, anyway) <code>I</code> as well (as opposed to replacing it with <code>_</code>).</p>



<a name="206389816"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206389816" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206389816">(Aug 09 2020 at 10:50)</a>:</h4>
<p>I've filed <a href="https://github.com/rust-lang/rust/issues/75326">#75326</a> about this so we can keep track of this issue somewhere more permanent than Zulip.</p>



<a name="206922131"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216091-t-compiler/wg-polymorphization/topic/symbol%20mangling%20v0%20%E2%9C%95%20polymorphisation/near/206922131" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> davidtwco <a href="https://rust-lang.github.io/zulip_archive/stream/216091-t-compiler/wg-polymorphization/topic/symbol.20mangling.20v0.20.E2.9C.95.20polymorphisation.html#206922131">(Aug 14 2020 at 12:05)</a>:</h4>
<p>Filed <a href="https://github.com/rust-lang/rust/issues/75518">#75518</a> to fix <a href="https://github.com/rust-lang/rust/issues/75326">#75326</a>.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>